package com.atguigu.tingshu.album.service.impl;

import java.math.BigDecimal;
import java.util.Date;

import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.service.AlbumAttrAndValueService;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.google.common.collect.Maps;

import java.util.ArrayList;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;


    @Autowired
    private AlbumInfoServiceImpl albumInfoServiceImpl;

    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Autowired
    private AlbumAttrAndValueService albumAttrAndValueService;


    @Autowired
    private TrackInfoMapper trackInfoMapper;


    @Transactional(rollbackFor = Exception.class)  // spring事务只能感知到运行时异常或者error
    @Override
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {


        AlbumInfoServiceImpl proxy = (AlbumInfoServiceImpl) AopContext.currentProxy();

        AlbumInfo albumInfo = new AlbumInfo();

        // 1.像基本信息表保存数据（album_info）
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        Long userId = AuthContextHolder.getUserId();
        albumInfo.setUserId(userId);
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        // 除了专辑免费的类型之外 其它两种类型设置免费级数
        if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())) {
            albumInfo.setTracksForFree(5);
        }

        albumInfoMapper.insert(albumInfo);

        // 2.像专辑属性值表保存数据（album_attr_value）
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                albumAttributeValue.setAlbumId(albumInfo.getId());
                albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
                albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
                albumAttributeValueMapper.insert(albumAttributeValue);
            }
        }
        // 3.初始化专辑统计表 （album_stat为专辑的四个统计维度赋初始值）
//        initAlbumStat(albumInfo.getId());没有任何问题
//        albumInfoServiceImpl.initAlbumStat(albumInfo.getId()); // 代理对象
        proxy.initAlbumStat(albumInfo.getId()); // 代理对象
    }

    @Override
    public IPage<AlbumListVo> findUserAlbumPage(IPage<AlbumListVo> albumInfoVoPage, AlbumInfoQuery albumInfoQuery) {

        return albumInfoMapper.findUserAlbumPage(albumInfoVoPage, albumInfoQuery);
    }

    @Override
    public AlbumInfo getAlbumInfo(Long albumId) {
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        if (null == albumInfo) {
            throw new GuiguException(201, "专辑不存在");
        }
        List<AlbumAttributeValue> attributeValues = albumAttributeValueMapper.selectList(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        albumInfo.setAlbumAttributeValueVoList(attributeValues);
        return albumInfo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateAlbumInfo(AlbumInfoVo albumInfoVo, Long userId, Long albumId) {

        // 1.修改专辑基本信息（最新的分类）
        // 1.1 查询该专辑的老数据
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        if (null == albumInfo) {
            throw new GuiguException(201, "专辑不存在");
        }
        BeanUtils.copyProperties(albumInfoVo, albumInfo);  // 有的就拷贝过去  没有的就用原来对象的

        if (albumInfoVo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_FREE)) {
            albumInfo.setTracksForFree(0);
            albumInfo.setDiscount(new BigDecimal("-1.00"));
            albumInfo.setVipDiscount(new BigDecimal("-1.00"));
            albumInfo.setPrice(new BigDecimal("0.00"));
        } else {
            albumInfo.setTracksForFree(5);
        }

        albumInfoMapper.updateById(albumInfo);

        // 2.修改专辑的标签信息
        // 2.1 删除这个专辑的老标签信息
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        // 2.2 新增这个专辑的新标签
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();

        List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            albumAttributeValue.setAlbumId(albumId);
            albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
            albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
            return albumAttributeValue;
        }).collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(albumAttributeValues)) {
            albumAttrAndValueService.saveBatch(albumAttributeValues);
        }


    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeAlbumInfo(Long albumId) {

        // 1.删除专辑的基本信息
        Long count = trackInfoMapper.selectCount(new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId, albumId));
        if (count > 0) {
            throw new GuiguException(201, "该专辑下存在声音，请勿删除");
        }
        albumInfoMapper.deleteById(albumId);

        // 2.删除专辑统计信息
        albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));

        // 3.删除专辑的标签信息
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));

    }

    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        LambdaQueryWrapper<AlbumInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AlbumInfo::getUserId, userId);
        lambdaQueryWrapper.eq(AlbumInfo::getIsDeleted, 0);
        return albumInfoMapper.selectList(lambdaQueryWrapper);
    }


    @Transactional
    public void initAlbumStat(Long albumId) {

        ArrayList<String> albumStatTypes = new ArrayList<>();
        albumStatTypes.add(SystemConstant.ALBUM_STAT_PLAY);
        albumStatTypes.add(SystemConstant.ALBUM_STAT_SUBSCRIBE);
        albumStatTypes.add(SystemConstant.ALBUM_STAT_BROWSE);
        albumStatTypes.add(SystemConstant.ALBUM_STAT_COMMENT);
        for (String albumStatType : albumStatTypes) {
            AlbumStat albumStat = new AlbumStat();
            albumStat.setAlbumId(albumId);
            albumStat.setStatType(albumStatType);
            albumStat.setStatNum(0);
            albumStatMapper.insert(albumStat);
        }
    }
}
